package com.flow.modules.dingtalk.service.impl;

import com.aliyun.dingtalkoauth2_1_0.Client;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.flow.modules.dingtalk.service.DingTalkService;
import com.flow.modules.dingtalk.utils.RedisUtil;
import com.taobao.api.ApiException;
import dm.jdbc.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author liuledong
 * @description: TODO
 * @date 2023/4/21 15:31
 */
@Slf4j
@Service
public class DingTalkServiceImpl implements DingTalkService {

    @Value("${dingding.appKey}")
    private String appKey;

    @Value("${dingding.appSecret}")
    private String appSecret;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 获取accessToken
     *
     * @return
     * @throws Exception
     */
    @Override
    public String getAccessToken() throws Exception {
        Config config = new Config();
        config.setProtocol("https");
        config.setRegionId("central");
        Client client = new Client(config);
        GetAccessTokenRequest getAccessTokenRequest = new GetAccessTokenRequest()
                .setAppKey(appKey)
                .setAppSecret(appSecret);
        try {
            GetAccessTokenResponse getAccessTokenResponse = client.getAccessToken(getAccessTokenRequest);
            String accessToken = getAccessTokenResponse.getBody().getAccessToken();
            //accessToken的有效期为7200秒（2小时），有效期内重复获取会返回相同结果并自动续期，过期后获取会返回新的accessToken
            boolean reds = redisUtil.set("accessToken", accessToken, 60 * 60 * 2L);
            return accessToken;
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                log.info(err.message);
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                log.info(err.message);
            }
        }
        return null;
    }

    /**
     * 根据accessToken获取部门列表
     *
     * @param accessToken
     * @param deptId
     * @return
     */
    public OapiV2DepartmentListsubResponse getDeptListByAccessToken(String accessToken, Long deptId) {
        try {
            if (StringUtil.isEmpty(accessToken)) {
                accessToken = getAccessToken();
            }
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
            OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
            if (deptId != null) {
                req.setDeptId(deptId);
            }
            req.setLanguage("zh_CN");
            OapiV2DepartmentListsubResponse rsp = client.execute(req, accessToken);
            return rsp;
        } catch (ApiException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据accessToken、deptId获取部门详细信息
     *
     * @param accessToken
     * @param deptId
     * @return
     */
    public OapiV2DepartmentGetResponse getDeptInfoById(String accessToken, Long deptId) {
        try {
            if (StringUtil.isEmpty(accessToken)) {
                accessToken = getAccessToken();
            }
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
            OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
            req.setDeptId(deptId);
            req.setLanguage("zh_CN");
            OapiV2DepartmentGetResponse rsp = client.execute(req, accessToken);
            return rsp;
        } catch (ApiException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 根据accessToken获取员工人数
     *
     * @param accessToken
     * @param onlyActive
     * @return
     */
    public OapiUserCountResponse getUserCountByAccessToken(String accessToken, Boolean onlyActive) {
        try {
            if (StringUtil.isEmpty(accessToken)) {
                accessToken = getAccessToken();
            }
            //获取员工总人数
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/count");
            OapiUserCountRequest req = new OapiUserCountRequest();
            req.setOnlyActive(onlyActive);
            OapiUserCountResponse rsp = client.execute(req, accessToken);
            return rsp;
        } catch (ApiException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据部门id、accessToken获取完整员工信息
     *
     * @param accessToken
     * @param deptId
     * @param cursor
     * @param size
     * @return
     */
    public OapiV2UserListResponse getUserInfoByDepts(String accessToken, Long deptId, Long cursor, Long size) {
        try {
            if (StringUtil.isEmpty(accessToken)) {
                accessToken = getAccessToken();
            }

            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/list");
            OapiV2UserListRequest req = new OapiV2UserListRequest();
            req.setDeptId(deptId);
            req.setCursor(cursor);
            req.setSize(size);
            req.setLanguage("zh_CN");
            OapiV2UserListResponse rsp = client.execute(req, accessToken);
            return rsp;
        } catch (ApiException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据员工id获取员工详细信息
     *
     * @param accessToken
     * @param userId
     * @return
     */
    public OapiV2UserGetResponse getUserInfoById(String accessToken, String userId) {
        try {
            if (StringUtil.isEmpty(accessToken)) {
                accessToken = getAccessToken();
            }
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.setUserid(userId);
            req.setLanguage("zh_CN");
            OapiV2UserGetResponse rsp = client.execute(req, accessToken);
            return rsp;
        } catch (ApiException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *
     * 获取考勤打卡详情
     *
     * @param accessToken
     * @param userIds
     * @param checkDateFrom
     * @param checkDateTo
     * @return OapiAttendanceListRecordResponse
     */
    public OapiAttendanceListRecordResponse getAttendanceByUserIds(String accessToken, List<String> userIds,
                                                                   String checkDateFrom, String checkDateTo) {
        try {
            if (StringUtil.isEmpty(accessToken)) {
                accessToken = getAccessToken();
            }
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/attendance/listRecord");
            OapiAttendanceListRecordRequest req = new OapiAttendanceListRecordRequest();
            req.setUserIds(userIds);
            req.setCheckDateFrom(checkDateFrom);
            req.setCheckDateTo(checkDateTo);
            OapiAttendanceListRecordResponse rsp = client.execute(req, accessToken);
            System.out.println(rsp.getBody());
            return rsp;
        } catch (ApiException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}
